import pygame
import os
import json
from typing import List, Tuple, Optional, Dict
from ..theme import Theme
from ..word_bank import WordBank
from ..user_profile import UserProfile
import logging

class WordBankView:
    def __init__(self, screen: pygame.Surface, theme: Theme, word_bank: WordBank, user_profile: UserProfile):
        self.screen = screen
        self.theme = theme
        self.word_bank = word_bank
        self.user_profile = user_profile
        
        # 界面尺寸
        self.width = screen.get_width()
        self.height = screen.get_height()
        
        # 词库列表
        self.word_banks = self.word_bank.list_word_banks()
        self.selected_bank = self.word_bank.current_bank
        
        # 获取项目根目录的绝对路径
        self.root_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
        
        # 获取可用词库列表
        self.wordbanks = self._get_available_wordbanks()
        self.selected = 0
        
        # 滚动相关
        self.scroll_offset = 0
        self.max_visible_banks = 5  # 一次显示的最大词库数量
        
        # 卡片尺寸和位置
        self.card_width = 700
        self.card_height = 120
        self.card_spacing = 15
        
        # 难度颜色映射
        self.difficulty_colors = {
            "入门": (94, 214, 174),    # 浅绿色
            "基础": (94, 114, 228),    # 蓝紫色（主题色）
            "中级": (250, 130, 76),    # 橙色
            "高级": (255, 86, 155),    # 粉色（强调色）
            "专业": (190, 46, 221),    # 紫色
            "未知难度": (150, 150, 150)  # 灰色
        }
        
        # 动画效果
        self.animation_progress = {}  # 用于存储每个卡片的动画进度
        self.hover_card = -1  # 当前悬停的卡片索引
        
        # 按钮区域
        self.buttons = {}
        self.refresh_buttons()
        
    def refresh_buttons(self) -> None:
        """刷新按钮"""
        self.buttons = {}
        
        # 添加返回按钮
        self.buttons["back"] = pygame.Rect(
            self.width/2 - 100, 
            self.height - 80, 
            200, 
            50
        )
        
        # 添加滚动按钮
        if len(self.wordbanks) > self.max_visible_banks:
            self.buttons["scroll_up"] = pygame.Rect(
                self.width - 80, 
                150, 
                40, 
                40
            )
            self.buttons["scroll_down"] = pygame.Rect(
                self.width - 80, 
                self.height - 150, 
                40, 
                40
            )
        
    def _get_available_wordbanks(self) -> List[Tuple[str, str, int, Dict]]:
        """获取可用的词库列表"""
        wordbanks = []
        try:
            # 获取所有可用词库
            bank_list = self.word_bank.list_word_banks()
            
            for bank_name in bank_list:
                try:
                    # 尝试加载词库以获取单词数量
                    self.word_bank.load_word_bank(bank_name)
                    word_count = len(self.word_bank.words)
                    
                    # 获取词库配置信息
                    bank_info = self.word_bank.get_bank_info(bank_name)
                    if bank_info:
                        display_name = bank_info['name']
                    else:
                        display_name = bank_name
                        bank_info = {}
                        
                    wordbanks.append((bank_name, display_name, word_count, bank_info))
                    
                except Exception as e:
                    logging.error(f"加载词库 {bank_name} 失败: {str(e)}")
                    # 如果加载失败，仍然显示在列表中，但不显示单词数量
                    wordbanks.append((bank_name, bank_name, 0, {}))
                    
        except Exception as e:
            logging.error(f"获取词库列表失败: {str(e)}")
        
        # 重新加载当前词库
        self.word_bank.load_word_bank(self.word_bank.current_bank)
        
        return sorted(wordbanks, key=lambda x: x[1])  # 按显示名称排序
        
    def handle_event(self, event: pygame.event.Event) -> Optional[str]:
        """处理事件"""
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                return "menu"
            elif event.key == pygame.K_UP:
                prev_selected = self.selected
                self.selected = max(0, self.selected - 1)
                # 调整滚动位置
                if self.selected < self.scroll_offset:
                    self.scroll_offset = self.selected
            elif event.key == pygame.K_DOWN:
                prev_selected = self.selected
                self.selected = min(len(self.wordbanks) - 1, self.selected + 1)
                # 调整滚动位置
                if self.selected >= self.scroll_offset + self.max_visible_banks:
                    self.scroll_offset = self.selected - self.max_visible_banks + 1
            elif event.key == pygame.K_RETURN:
                # 选择词库
                if self.wordbanks:
                    selected_wordbank = self.wordbanks[self.selected][0]
                    if self.word_bank.set_word_bank(selected_wordbank):
                        logging.info(f"成功选择词库: {selected_wordbank}")
                        # 保存选择
                        self._save_selected_wordbank(selected_wordbank)
                    else:
                        logging.error(f"选择词库失败: {selected_wordbank}")
                return "menu"
                
        elif event.type == pygame.MOUSEBUTTONDOWN:
            mouse_pos = pygame.mouse.get_pos()
            
            # 处理鼠标点击
            if event.button == 1:  # 左键点击
                # 检查词库卡片
                for i in range(min(self.max_visible_banks, len(self.wordbanks) - self.scroll_offset)):
                    index = i + self.scroll_offset
                    card_y = 180 + i * (self.card_height + self.card_spacing)
                    card_rect = pygame.Rect(
                        self.width/2 - self.card_width/2,
                        card_y,
                        self.card_width,
                        self.card_height
                    )
                    
                    if card_rect.collidepoint(mouse_pos):
                        self.selected = index
                        selected_wordbank = self.wordbanks[self.selected][0]
                        if self.word_bank.set_word_bank(selected_wordbank):
                            logging.info(f"成功选择词库: {selected_wordbank}")
                            # 保存选择
                            self._save_selected_wordbank(selected_wordbank)
                        else:
                            logging.error(f"选择词库失败: {selected_wordbank}")
                        return "menu"
                
                # 检查返回按钮
                if self.buttons.get("back") and self.buttons["back"].collidepoint(mouse_pos):
                    return "menu"
                
                # 检查滚动按钮
                if self.buttons.get("scroll_up") and self.buttons["scroll_up"].collidepoint(mouse_pos):
                    self.scroll_offset = max(0, self.scroll_offset - 1)
                
                if self.buttons.get("scroll_down") and self.buttons["scroll_down"].collidepoint(mouse_pos):
                    max_offset = max(0, len(self.wordbanks) - self.max_visible_banks)
                    self.scroll_offset = min(max_offset, self.scroll_offset + 1)
            
            # 处理鼠标滚轮
            elif event.button == 4:  # 滚轮向上
                self.scroll_offset = max(0, self.scroll_offset - 1)
            elif event.button == 5:  # 滚轮向下
                max_offset = max(0, len(self.wordbanks) - self.max_visible_banks)
                self.scroll_offset = min(max_offset, self.scroll_offset + 1)
                    
        elif event.type == pygame.MOUSEMOTION:
            mouse_pos = pygame.mouse.get_pos()
            
            # 重置悬停卡片
            self.hover_card = -1
            
            # 检测鼠标悬停在哪个卡片上
            for i in range(min(self.max_visible_banks, len(self.wordbanks) - self.scroll_offset)):
                index = i + self.scroll_offset
                card_y = 180 + i * (self.card_height + self.card_spacing)
                card_rect = pygame.Rect(
                    self.width/2 - self.card_width/2,
                    card_y,
                    self.card_width,
                    self.card_height
                )
                
                if card_rect.collidepoint(mouse_pos):
                    self.hover_card = index
                    break
                    
        return None
        
    def _save_selected_wordbank(self, wordbank: str) -> None:
        """保存选中的词库"""
        try:
            # 确保目录存在
            os.makedirs(os.path.join("data", "user_data"), exist_ok=True)
            
            # 保存选择的词库
            with open(os.path.join("data", "user_data", "selected_wordbank.txt"), 'w', encoding='utf-8') as f:
                f.write(wordbank)
        except Exception as e:
            logging.error(f"保存词库选择失败: {str(e)}")
        
    def draw(self):
        """绘制词库选择界面"""
        # 清空屏幕
        self.screen.fill(self.theme.background_color)
        
        # 绘制标题卡片
        title_card_rect = pygame.Rect(self.width/2 - 250, 30, 500, 80)
        self.theme.draw_card(self.screen, title_card_rect, with_shadow=True)
        
        # 绘制标题
        self.theme.draw_text(
            self.screen, 
            "选择词库", 
            (self.width/2, 70), 
            center=True, 
            size=36, 
            color=self.theme.primary_color,
            shadow=True
        )
        
        # 绘制内容区域背景
        content_rect = pygame.Rect(
            self.width/2 - self.card_width/2 - 20, 
            150, 
            self.card_width + 40, 
            self.height - 250
        )
        self.theme.draw_card(self.screen, content_rect, with_shadow=True)
        
        # 绘制词库卡片
        if not self.wordbanks:
            # 没有词库时显示提示
            self.theme.draw_text(
                self.screen, 
                "没有找到可用的词库", 
                (self.width/2, self.height/2 - 50), 
                center=True, 
                size=24,
                color=self.theme.text_color
            )
        else:
            # 显示词库卡片
            for i in range(min(self.max_visible_banks, len(self.wordbanks) - self.scroll_offset)):
                index = i + self.scroll_offset
                card_y = 180 + i * (self.card_height + self.card_spacing)
                
                # 从词库信息中获取数据
                bank_id, display_name, word_count, bank_info = self.wordbanks[index]
                
                # 检查动画状态
                is_selected = index == self.selected
                is_hovered = index == self.hover_card
                
                # 设置卡片状态
                card_state = "selected" if is_selected else ("hover" if is_hovered else "normal")
                
                # 绘制词库卡片
                self._draw_wordbank_card(
                    display_name,
                    bank_id,
                    word_count,
                    bank_info,
                    card_y,
                    card_state
                )
        
        # 绘制滚动指示器（如果需要）
        if len(self.wordbanks) > self.max_visible_banks:
            # 绘制向上滚动按钮
            if self.scroll_offset > 0:
                scroll_up_rect = self.buttons["scroll_up"]
                mouse_pos = pygame.mouse.get_pos()
                is_hover = scroll_up_rect.collidepoint(mouse_pos)
                
                self.theme.draw_rounded_rect(
                    self.screen,
                    scroll_up_rect,
                    self.theme.primary_color if is_hover else (*self.theme.primary_color[:3], 150),
                    radius=20
                )
                
                # 绘制向上箭头
                arrow_points = [
                    (scroll_up_rect.centerx, scroll_up_rect.top + 10),
                    (scroll_up_rect.left + 10, scroll_up_rect.centery + 5),
                    (scroll_up_rect.right - 10, scroll_up_rect.centery + 5)
                ]
                pygame.draw.polygon(
                    self.screen,
                    self.theme.button_text_color,
                    arrow_points
                )
            
            # 绘制向下滚动按钮
            max_offset = len(self.wordbanks) - self.max_visible_banks
            if self.scroll_offset < max_offset:
                scroll_down_rect = self.buttons["scroll_down"]
                mouse_pos = pygame.mouse.get_pos()
                is_hover = scroll_down_rect.collidepoint(mouse_pos)
                
                self.theme.draw_rounded_rect(
                    self.screen,
                    scroll_down_rect,
                    self.theme.primary_color if is_hover else (*self.theme.primary_color[:3], 150),
                    radius=20
                )
                
                # 绘制向下箭头
                arrow_points = [
                    (scroll_down_rect.centerx, scroll_down_rect.bottom - 10),
                    (scroll_down_rect.left + 10, scroll_down_rect.centery - 5),
                    (scroll_down_rect.right - 10, scroll_down_rect.centery - 5)
                ]
                pygame.draw.polygon(
                    self.screen,
                    self.theme.button_text_color,
                    arrow_points
                )
                
            # 绘制滚动条
            scrollbar_height = content_rect.height * min(1, self.max_visible_banks / len(self.wordbanks))
            scrollbar_y = content_rect.top + (content_rect.height - scrollbar_height) * (self.scroll_offset / max(1, max_offset))
            
            scrollbar_rect = pygame.Rect(
                content_rect.right - 10,
                scrollbar_y,
                5,
                scrollbar_height
            )
            
            self.theme.draw_rounded_rect(
                self.screen,
                scrollbar_rect,
                (*self.theme.primary_color[:3], 150),
                radius=3
            )
        
        # 绘制返回按钮
        back_button = self.buttons["back"]
        mouse_pos = pygame.mouse.get_pos()
        is_hover = back_button.collidepoint(mouse_pos)
        
        self.theme.draw_button(
            self.screen,
            back_button,
            "返回主菜单",
            is_hover=is_hover
        )
        
        # 绘制操作提示卡片
        help_card_rect = pygame.Rect(20, self.height - 120, 180, 100)
        self.theme.draw_rounded_rect(
            self.screen, 
            help_card_rect, 
            (*self.theme.card_bg_color[:3], 200),  # 半透明
            border=1
        )
        
        # 绘制操作说明
        instructions = [
            "↑↓: 选择词库",
            "Enter: 确认选择",
            "鼠标: 点击选择"
        ]
        for i, instruction in enumerate(instructions):
            self.theme.draw_text(
                self.screen, 
                instruction,
                (help_card_rect.left + 20, help_card_rect.top + 25 + i*25), 
                size=16,
                color=self.theme.text_color
            )
    
    def _draw_wordbank_card(self, name: str, bank_id: str, word_count: int, bank_info: Dict, y_pos: int, state: str):
        """绘制词库卡片
        
        Args:
            name: 词库显示名称
            bank_id: 词库ID
            word_count: 单词数量
            bank_info: 词库信息
            y_pos: 卡片Y坐标
            state: 卡片状态（normal, hover, selected）
        """
        # 获取难度
        difficulty = self.word_bank.get_difficulty_level(bank_id)
        difficulty_color = self.difficulty_colors.get(difficulty, self.difficulty_colors["未知难度"])
        
        # 获取标签
        tags = bank_info.get('tags', [])
        
        # 创建卡片矩形
        card_rect = pygame.Rect(
            self.width/2 - self.card_width/2,
            y_pos,
            self.card_width,
            self.card_height
        )
        
        # 根据状态确定卡片样式
        if state == "selected":
            # 选中状态：突出显示
            self.theme.draw_card(
                self.screen, 
                card_rect, 
                with_shadow=True, 
                border=2
            )
            border_color = self.theme.primary_color
            # 绘制左侧彩色条
            color_bar = pygame.Rect(card_rect.left, card_rect.top, 10, card_rect.height)
            self.theme.draw_rounded_rect(
                self.screen,
                color_bar,
                difficulty_color,
                radius=0
            )
        elif state == "hover":
            # 悬停状态：轻微突出
            self.theme.draw_card(
                self.screen, 
                card_rect, 
                with_shadow=True
            )
            border_color = (*self.theme.primary_color[:3], 150)
            # 绘制左侧彩色条
            color_bar = pygame.Rect(card_rect.left, card_rect.top, 6, card_rect.height)
            self.theme.draw_rounded_rect(
                self.screen,
                color_bar,
                difficulty_color,
                radius=0
            )
        else:
            # 普通状态
            self.theme.draw_card(
                self.screen, 
                card_rect, 
                with_shadow=False
            )
            border_color = self.theme.border_color
            # 绘制左侧彩色条（较细）
            color_bar = pygame.Rect(card_rect.left, card_rect.top, 3, card_rect.height)
            self.theme.draw_rounded_rect(
                self.screen,
                color_bar,
                (*difficulty_color[:3], 150),  # 降低透明度
                radius=0
            )
        
        # 绘制词库名称（左上角）
        self.theme.draw_text(
            self.screen,
            name,
            (card_rect.left + 25, card_rect.top + 30),
            center=False,
            size=28,  # 增大字体大小
            color=self.theme.primary_color if state in ["selected", "hover"] else self.theme.text_color
        )
        
        # 绘制单词数量（右上角）- 优化显示样式
        count_text = f"{word_count} 词"
        count_width = self.theme.get_text_width(count_text, size=22)  # 获取文本宽度
        count_bg_rect = pygame.Rect(
            card_rect.right - count_width - 30,  # 背景矩形左侧位置
            card_rect.top + 20,
            count_width + 20,  # 增加一些内边距
            30
        )
        
        # 绘制数量背景
        self.theme.draw_rounded_rect(
            self.screen,
            count_bg_rect,
            (*difficulty_color[:3], 30),  # 半透明背景
            radius=15
        )
        
        # 绘制数量文本
        self.theme.draw_text(
            self.screen,
            count_text,
            (count_bg_rect.centerx, count_bg_rect.centery),
            center=True,
            size=20,
            color=difficulty_color
        )
        
        # 绘制词库描述（如下方）
        description = bank_info.get('description', '')
        if description:
            # 截断过长的描述
            max_desc_len = 60
            if len(description) > max_desc_len:
                description = description[:max_desc_len] + "..."
                
            self.theme.draw_text(
                self.screen,
                description,
                (card_rect.left + 25, card_rect.top + 68),
                center=False,
                size=16,
                color=(*self.theme.text_color[:3], 180)  # 降低透明度
            )
            
        # 获取附加信息（比如"大学英语四级词汇"）
        additional_info = bank_info.get('additional_info', '')
        if not additional_info and '大学' in name:
            # 如果没有附加信息但名称中包含"大学"，生成一个默认的
            if '四级' in name or 'cet4' in bank_id.lower():
                additional_info = "大学英语四级词汇"
            elif '六级' in name or 'cet6' in bank_id.lower():
                additional_info = "大学英语六级词汇"
        elif not additional_info:
            if '小学' in name:
                additional_info = "小学英语基础词汇"
            elif '初中' in name:
                additional_info = "初中英语词汇"
            elif '高中' in name:
                additional_info = "高中英语词汇"
                
        # 绘制附加信息
        if additional_info:
            self.theme.draw_text(
                self.screen,
                additional_info,
                (card_rect.left + 25, card_rect.bottom - 68),
                center=False,
                size=16,
                color=(*self.theme.text_color[:3], 150)  # 降低透明度
            )
        
        # 标签容器 - 改为底部水平布局
        tags_container_rect = pygame.Rect(
            card_rect.left + 25,
            card_rect.bottom - 40, 
            card_rect.width - 50,
            30
        )
        
        # 绘制难度和标签（底部排列）
        # 首先绘制难度标签
        if difficulty != "未知难度":
            difficulty_label = pygame.Rect(
                tags_container_rect.left, 
                tags_container_rect.top, 
                80, 
                26
            )
            
            self.theme.draw_rounded_rect(
                self.screen,
                difficulty_label,
                (*difficulty_color[:3], 50),  # 降低透明度
                radius=13
            )
            
            self.theme.draw_text(
                self.screen,
                difficulty,
                (difficulty_label.centerx, difficulty_label.centery),
                center=True,
                size=14,
                color=difficulty_color
            )
            
            # 更新下一个标签的起始位置
            next_tag_x = difficulty_label.right + 10
        else:
            next_tag_x = tags_container_rect.left
        
        # 然后绘制其他标签
        if tags:
            # 只显示最多3个标签
            display_tags = tags[:3]
            
            for tag in display_tags:
                # 计算标签宽度 (根据文本长度调整)
                tag_width = max(70, self.theme.get_text_width(tag, size=14) + 20)
                
                # 检查是否超出容器
                if next_tag_x + tag_width > tags_container_rect.right:
                    break
                    
                tag_rect = pygame.Rect(next_tag_x, tags_container_rect.top, tag_width, 26)
                
                # 为不同类型的标签使用不同颜色
                tag_color = self.theme.secondary_color
                if tag.lower() in ["考试", "test", "exam"]:
                    tag_color = (250, 130, 76)  # 橙色
                elif tag.lower() in ["基础", "basic", "入门"]:
                    tag_color = (94, 214, 174)  # 绿色
                elif tag.lower() in ["进阶", "高级", "advanced"]:
                    tag_color = (255, 86, 155)  # 粉色
                
                self.theme.draw_rounded_rect(
                    self.screen,
                    tag_rect,
                    (*tag_color[:3], 40),  # 降低透明度
                    radius=13
                )
                
                self.theme.draw_text(
                    self.screen,
                    tag,
                    (tag_rect.centerx, tag_rect.centery),
                    center=True,
                    size=14,
                    color=tag_color
                )
                
                # 更新下一个标签的位置
                next_tag_x = tag_rect.right + 10 